﻿#include "DAAppRibbonArea.h"
#include "AppMainWindow.h"
#include "ui_AppMainWindow.h"
// SARibbon
#include "SARibbonBar.h"
#include "SARibbonCategory.h"
#include "SARibbonPannel.h"
#include "SARibbonContextCategory.h"
#include "SARibbonQuickAccessBar.h"
#include "SARibbonLineWidgetContainer.h"
#include "SARibbonComboBox.h"
#include "SARibbonButtonGroupWidget.h"
#include "SARibbonMenu.h"
// stl
#include <memory>
// Qt
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
#include <QSignalBlocker>
// ui
#include "DAWaitCursorScoped.h"
// Dialog
#include "DAPluginManagerDialog.h"
// Py
#include "DAPyScripts.h"
#include "pandas/DAPyDataFrame.h"
#include "numpy/DAPyDType.h"
// api
#include "DACoreInterface.h"
#include "DADataManagerInterface.h"
#include "DAAppDockingAreaInterface.h"
#include "DAAppDockingArea.h"
#include "DAAppCommand.h"
// Qt-Advanced-Docking-System
#include "DockManager.h"
#include "DockAreaWidget.h"
// command
#include "DACommandsDataManager.h"
// Widget
#include "DADataOperateWidget.h"
#include "DADataOperateOfDataFrameWidget.h"
#include "DAPyDTypeComboBox.h"
#include "DAWorkFlowOperateWidget.h"
// Dialog
#include "DARenameColumnsNameDialog.h"
// project
#include "DAProject.h"

//===================================================
// using DA namespace -- 禁止在头文件using！！
//===================================================

using namespace DA;

//===================================================
// DAAppRibbonArea
//===================================================
//快速链接信号槽
#define DAAPPRIBBONAREA_ACTION_BIND(actionname, functionname)                                                          \
    connect(actionname, &QAction::triggered, this, &DAAppRibbonArea::functionname)

//未实现的功能标记
#define DAAPPRIBBONAREA_PASS()                                                                                         \
    QMessageBox::warning(app(), tr("warning"), tr("The current function is not implemented, only the UI is reserved, please pay attention: https://gitee.com/czyt1988/data-work-flow"))

DAAppRibbonArea::DAAppRibbonArea(DAAppUIInterface* u) : DAAppRibbonAreaInterface(u), m_dockArea(nullptr)
{
    m_app = qobject_cast< AppMainWindow* >(u->mainWindow());
    m_dataManagerStack.setUndoLimit(20);
    buildAction();
    buildRibbon();
    initConnection();
    initScripts();
    retranslateUi();
}

DAAppRibbonArea::~DAAppRibbonArea()
{
}

/**
 * @brief 构建所有的action
 */
void DAAppRibbonArea::buildAction()
{
    AppMainWindow* app = m_app;  //为了给lamda捕获
    DACoreInterface* c = core();
    auto createAction  = [ app, c ](const char* objname, const char* iconpath) -> QAction* {
        QAction* act = new QAction(app);
        act->setObjectName(QString::fromUtf8(objname));
        QIcon icon(iconpath);
        act->setIcon(icon);
        act->setEnabled(c->isPythonInterpreterInitialized());  //如果python没有初始化，就禁用按钮
        return act;
    };
    // Main Category
    m_actionOpen   = createAction("actionOpen", ":/Icon/Icon/file.svg");
    m_actionSave   = createAction("actionSave", ":/Icon/Icon/save.svg");
    m_actionSaveAs = createAction("actionSaveAs", ":/Icon/Icon/save-as.svg");
    m_actionRedo   = nullptr;
    m_actionUndo   = nullptr;
    // Data Category
    m_actionAddData            = createAction("actionAddData", ":/Icon/Icon/addData.svg");
    m_actionRemoveRow          = createAction("actionRemoveRow", ":/Icon/Icon/removeRow.svg");
    m_actionRemoveColumn       = createAction("actionRemoveColumn", ":/Icon/Icon/removeColumn.svg");
    m_actionInsertRow          = createAction("actionInsertRow", ":/Icon/Icon/insertRow.svg");
    m_actionInsertRowAbove     = createAction("actionInsertRowAbove", ":/Icon/Icon/insertRowAbove.svg");
    m_actionInsertColumnRight  = createAction("actionInsertColumnRight", ":/Icon/Icon/insertColumnRight.svg");
    m_actionInsertColumnLeft   = createAction("actionInsertColumnLeft", ":/Icon/Icon/insertColumnLeft.svg");
    m_actionRenameColumns      = createAction("actionRenameColumns", ":/Icon/Icon/renameColumns.svg");
    m_actionRemoveCell         = createAction("actionRemoveCell", ":/Icon/Icon/removeCell.svg");
    m_actionCastToNum          = createAction("actionCastToNum", ":/Icon/Icon/castToNum.svg");
    m_actionCastToString       = createAction("actionCastToString", ":/Icon/Icon/castToString.svg");
    m_actionCastToDatetime     = createAction("actionCastToDatetime", ":/Icon/Icon/castToDatetime.svg");
    m_actionCreateDataDescribe = createAction("actionCreateDataDescribe", ":/Icon/Icon/dataDescribe.svg");
    m_actionChangeToIndex      = createAction("actionCreateDataDescribe", ":/Icon/Icon/changeToIndex.svg");
    m_menuInsertRow            = new SARibbonMenu(app);
    m_menuInsertRow->setObjectName("menuInsertRow");
    m_menuInsertRow->addAction(m_actionInsertRowAbove);
    m_menuInsertColumn = new SARibbonMenu(app);
    m_menuInsertColumn->setObjectName("menuInsertColumn");
    m_menuInsertColumn->addAction(m_actionInsertColumnLeft);
    // View Category
    m_actionShowWorkFlowArea   = createAction("actionShowWorkFlowArea", ":/Icon/Icon/showWorkFlow.svg");
    m_actionShowChartArea      = createAction("actionShowChartArea", ":/Icon/Icon/showChart.svg");
    m_actionShowDataArea       = createAction("actionShowDataArea", ":/Icon/Icon/showTable.svg");
    m_actionShowMessageLogView = createAction("actionShowMessageLogView", ":/Icon/Icon/showInfomation.svg");
    m_actionShowSettingWidget  = createAction("actionShowSettingWidget", ":/Icon/Icon/showSettingWidget.svg");
    // Config Category
    m_actionPluginManager = createAction("actionPluginManager", ":/Icon/Icon/plugin.svg");
}

void DAAppRibbonArea::retranslateUi()
{
    ribbonBar()->applicationButton()->setText(tr("File"));  //文件

    m_categoryMain->setCategoryName(tr("Main"));                        //主页
    m_pannelMainFileOpt->setPannelName(tr("File Operation"));           //文件操作
    m_pannelMainDataOpt->setPannelName(tr("Data Operation"));           //文件操作
    m_categoryData->setCategoryName(tr("Data"));                        //数据
    m_pannelDataOperate->setPannelName(tr("Data Operation"));           //数据操作
    m_categoryView->setCategoryName(tr("View"));                        //视图
    m_pannelViewMainView->setPannelName(tr("Display"));                 //视图显示
    m_categoryConfig->setCategoryName(tr("Config"));                    //配置
    m_pannelConfigMain->setPannelName(tr("Main Config"));               //主配置
    m_contextDataFrame->setContextTitle(tr("DataFrame"));               ///< DataFrame
    m_categoryDataframeOperate->setCategoryName(tr("Operate"));         ///< DataFrame -> Operate
    m_pannelDataframeOperateAxes->setPannelName(tr("Axes"));            ///< DataFrame -> Operate -> Axes
    m_pannelDataframeOperateDType->setPannelName(tr("Type"));           ///< DataFrame -> Type
    m_comboxColumnTypesContainer->setPrefix(tr("Type"));                ///< DataFrame -> Type -> Type
    m_pannelDataframeOperateStatistic->setPannelName(tr("Statistic"));  ///< DataFrame -> Statistic
    //
    m_app->setWindowTitle(tr("Data Work Flow"));
    // Main Category
    m_actionOpen->setText(tr("Open"));
    m_actionSave->setText(tr("Save"));
    m_actionSaveAs->setText(tr("Save As"));
    m_actionRenameColumns->setText(tr("Rename Columns"));
    retranslateRedoUndo();
    // Data Category
    m_actionAddData->setText(tr("Add Data"));                      // cn:添加数据
    m_actionRemoveRow->setText(tr("Remove Row"));                  // cn:删除行
    m_actionRemoveColumn->setText(tr("Remove Column"));            // cn:删除列
    m_actionRemoveCell->setText(tr("Remove Cell"));                // cn:移除单元格
    m_actionInsertRow->setText(tr("Insert Row"));                  // cn:插入行
    m_actionInsertRowAbove->setText(tr("Insert Row(Above)"));      // cn:插入行(上)
    m_actionInsertColumnRight->setText(tr("Insert Column"));       // cn:插入列(右)
    m_actionInsertColumnLeft->setText(tr("Insert Column(Left)"));  // cn:插入列(左)
    m_actionCastToNum->setText(tr("to num"));
    m_actionCastToNum->setToolTip(tr("cast to num type"));  // cn:转换为数值类型
    m_actionCastToString->setText(tr("to str"));
    m_actionCastToString->setToolTip(tr("cast to string type"));  // cn:转换为字符串类型
    m_actionCastToDatetime->setText(tr("to datetime"));
    m_actionCastToDatetime->setToolTip(tr("cast to datetime type"));  // cn:转换为日期类型
    m_actionCreateDataDescribe->setText(tr("Data Describe"));         // cn:数据描述
    m_actionChangeToIndex->setText(tr("To Index"));                   // cn:转换为索引
    // View Category
    m_actionShowWorkFlowArea->setText(tr("Show Work Flow Area"));
    m_actionShowChartArea->setText(tr("Show Chart Area"));
    m_actionShowDataArea->setText(tr("Show Table Area"));
    m_actionShowMessageLogView->setText(tr("Show Infomation Window"));
    m_actionShowSettingWidget->setText(tr("Show Setting Window"));
    // Config Category
    m_actionPluginManager->setText(tr("Plugin Config"));
}

void DAAppRibbonArea::initConnection()
{
    // Main Category
    DAAPPRIBBONAREA_ACTION_BIND(m_actionOpen, onActionOpenTriggered);
    // Data Category
    DAAPPRIBBONAREA_ACTION_BIND(m_actionAddData, onActionAddDataTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionInsertRow, onActionInsertRowTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionInsertRowAbove, onActionInsertRowAboveTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionInsertColumnRight, onActionInsertColumnRightTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionInsertColumnLeft, onActionInsertColumnLeftTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionRemoveRow, onActionRemoveRowTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionRemoveColumn, onActionRemoveColumnTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionRemoveCell, onActionRemoveCellTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionRenameColumns, onActionRenameColumnsTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionCreateDataDescribe, onActionCreateDataDescribeTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionCastToNum, onActionCastToNumTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionCastToString, onActionCastToStringTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionCastToDatetime, onActionCastToDatetimeTriggered);
    //不知为何使用函数指针无法关联信号和槽
    // connect(m_comboxColumnTypes, &DAPyDTypeComboBox::currentDTypeChanged, this,&DAAppRibbonArea::onComboxColumnTypesCurrentDTypeChanged);
    // QObject::connect: signal not found in DAPyDTypeComboBox
    connect(m_comboxColumnTypes, SIGNAL(currentDTypeChanged(DAPyDType)), this, SLOT(onComboxColumnTypesCurrentDTypeChanged(DAPyDType)));
    DAAPPRIBBONAREA_ACTION_BIND(m_actionChangeToIndex, onActionChangeToIndexTriggered);
    // View Category
    DAAPPRIBBONAREA_ACTION_BIND(m_actionShowWorkFlowArea, onActionShowWorkFlowAreaTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionShowChartArea, onActionShowChartAreaTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionShowDataArea, onActionShowDataAreaTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionShowMessageLogView, onActionShowMessageLogViewTriggered);
    DAAPPRIBBONAREA_ACTION_BIND(m_actionShowSettingWidget, onActionSettingWidgetTriggered);
    // Config Category
    DAAPPRIBBONAREA_ACTION_BIND(m_actionPluginManager, onActionPluginManagerTriggered);
}

void DAAppRibbonArea::buildRibbon()
{
    ribbonBar()->setRibbonStyle(SARibbonBar::WpsLiteStyleTwoRow);
    buildRibbonMainCategory();
    buildRibbonDataCategory();
    buildRibbonViewCategory();
    buildRibbonConfigCategory();
    buildRibbonQuickAccessBar();
    //上下文标签
    buildContextCategoryDataFrame();
}

/**
 * @brief 构建主页标签
 */
void DAAppRibbonArea::buildRibbonMainCategory()
{
    m_categoryMain = new SARibbonCategory(app());
    m_categoryMain->setObjectName(QStringLiteral("categoryMain"));
    m_pannelMainFileOpt = new SARibbonPannel(m_categoryMain);
    m_pannelMainFileOpt->setObjectName(QStringLiteral("pannelCommon"));
    m_pannelMainFileOpt->addLargeAction(m_actionOpen);
    m_pannelMainFileOpt->addSmallAction(m_actionSave);
    m_pannelMainFileOpt->addSmallAction(m_actionSaveAs);
    m_categoryMain->addPannel(m_pannelMainFileOpt);
    m_pannelMainDataOpt = new SARibbonPannel(m_categoryMain);
    m_pannelMainDataOpt->addLargeAction(m_actionAddData);
    m_categoryMain->addPannel(m_pannelMainDataOpt);
    ribbonBar()->addCategoryPage(m_categoryMain);  //主页
}

/**
 * @brief 构建数据标签
 */
void DAAppRibbonArea::buildRibbonDataCategory()
{
    m_categoryData = new SARibbonCategory(app());
    m_categoryData->setObjectName(QStringLiteral("categoryData"));
    m_pannelDataOperate = new SARibbonPannel(m_categoryData);
    m_pannelDataOperate->setObjectName(QStringLiteral("pannelDataOperate"));
    m_pannelDataOperate->addLargeAction(m_actionAddData);
    m_categoryData->addPannel(m_pannelDataOperate);
    ribbonBar()->addCategoryPage(m_categoryData);  //视图
}

/**
 * @brief 构建视图标签
 */
void DAAppRibbonArea::buildRibbonViewCategory()
{
    m_categoryView = new SARibbonCategory(app());
    m_categoryView->setObjectName(QStringLiteral("categoryView"));
    m_pannelViewMainView = new SARibbonPannel(m_categoryView);
    m_pannelViewMainView->setObjectName(QStringLiteral("pannelViewMainView"));
    m_pannelViewMainView->addLargeAction(m_actionShowWorkFlowArea);
    m_pannelViewMainView->addLargeAction(m_actionShowChartArea);
    m_pannelViewMainView->addLargeAction(m_actionShowDataArea);
    m_pannelViewMainView->addSeparator();
    m_pannelViewMainView->addSmallAction(m_actionShowMessageLogView);
    m_pannelViewMainView->addSmallAction(m_actionShowSettingWidget);
    m_categoryView->addPannel(m_pannelViewMainView);
    ribbonBar()->addCategoryPage(m_categoryView);  //视图
}

/**
 * @brief 配置标签
 */
void DAAppRibbonArea::buildRibbonConfigCategory()
{
    m_categoryConfig = new SARibbonCategory(app());
    m_categoryConfig->setObjectName(QStringLiteral("categoryConfig"));
    m_pannelConfigMain = new SARibbonPannel(m_categoryConfig);
    m_pannelConfigMain->setObjectName(QStringLiteral("pannelConfigMain"));
    m_pannelConfigMain->addAction(m_actionPluginManager);
    m_categoryConfig->addPannel(m_pannelConfigMain);
    ribbonBar()->addCategoryPage(m_categoryConfig);  //视图
}

/**
 * @brief 构建ribbon的QuickAccessBar
 */
void DAAppRibbonArea::buildRibbonQuickAccessBar()
{
}

/**
 * @brief 构建DataFrame上下文标签
 */
void DAAppRibbonArea::buildContextCategoryDataFrame()
{
    m_contextDataFrame         = ribbonBar()->addContextCategory(tr("DataFrame"));
    m_categoryDataframeOperate = m_contextDataFrame->addCategoryPage(tr("Operate"));
    // Axes pannel
    m_pannelDataframeOperateAxes = m_categoryDataframeOperate->addPannel(tr("Axes"));
    m_pannelDataframeOperateAxes->addLargeActionMenu(m_actionInsertRow, m_menuInsertRow);
    m_pannelDataframeOperateAxes->addLargeActionMenu(m_actionInsertColumnRight, m_menuInsertColumn);
    m_pannelDataframeOperateAxes->addLargeAction(m_actionRemoveCell);
    m_pannelDataframeOperateAxes->addMediumAction(m_actionRemoveRow);
    m_pannelDataframeOperateAxes->addMediumAction(m_actionRemoveColumn);
    m_pannelDataframeOperateAxes->addSeparator();
    m_pannelDataframeOperateAxes->addLargeAction(m_actionRenameColumns);
    m_pannelDataframeOperateAxes->addLargeAction(m_actionChangeToIndex);
    // Type pannel
    m_pannelDataframeOperateDType = m_categoryDataframeOperate->addPannel(tr("Type"));
    m_comboxColumnTypesContainer  = new SARibbonLineWidgetContainer(m_pannelDataframeOperateDType);
    m_comboxColumnTypes           = new DAPyDTypeComboBox(m_comboxColumnTypesContainer);
    m_comboxColumnTypes->setMinimumWidth(m_app->fontMetrics().width("timedelta64(scoll)"));  //设置最小宽度
    m_comboxColumnTypesContainer->setPrefix(tr("Type"));
    m_comboxColumnTypesContainer->setWidget(m_comboxColumnTypes);
    m_pannelDataframeOperateDType->addWidget(m_comboxColumnTypesContainer, SARibbonPannelItem::Medium);
    m_castActionsButtonGroup = new SARibbonButtonGroupWidget();
    m_castActionsButtonGroup->addAction(m_actionCastToNum);
    m_castActionsButtonGroup->addAction(m_actionCastToString);
    m_castActionsButtonGroup->addSeparator();
    m_castActionsButtonGroup->addAction(m_actionCastToDatetime);
    m_pannelDataframeOperateDType->addWidget(m_castActionsButtonGroup, SARibbonPannelItem::Medium);
    // Statistic Pannel
    m_pannelDataframeOperateStatistic = m_categoryDataframeOperate->addPannel(tr("Statistic"));
    m_pannelDataframeOperateStatistic->addLargeAction(m_actionCreateDataDescribe);
}

/**
 * @brief 脚本定义的内容初始化
 */
void DAAppRibbonArea::initScripts()
{
    if (!core()->isPythonInterpreterInitialized()) {
        return;
    }
    m_fileReadFilters = QStringList(DAPyScripts::getInstance().getIO().getFileReadFilters());
    qDebug() << m_fileReadFilters;
}

void DAAppRibbonArea::retranslateRedoUndo()
{
    if (m_actionRedo) {
        m_actionRedo->setText(QCoreApplication::translate("DAAppRibbonArea", "Redo", nullptr));
    }
    if (m_actionUndo) {
        m_actionUndo->setText(QCoreApplication::translate("DAAppRibbonArea", "Undo", nullptr));
    }
}

AppMainWindow* DAAppRibbonArea::app() const
{
    return (m_app);
}

SARibbonBar* DAAppRibbonArea::ribbonBar() const
{
    return (app()->ribbonBar());
}

/**
 * @brief mian标签
 * @return
 */
SARibbonCategory* DAAppRibbonArea::getRibbonCategoryMain() const
{
    return (m_categoryMain);
}

QStringList DAAppRibbonArea::getFileReadFilters() const
{
    return m_fileReadFilters;
}
/**
 * @brief 由于无法判断DAAppRibbonArea和DAAppDockingArea的创建顺序，因此DAAppDockingArea的指针手动设置进去
 * @param d
 */
void DAAppRibbonArea::setDockAreaInterface(DAAppDockingArea* d)
{
    m_dockArea = d;
    connect(d->dockManager(), &ads::CDockManager::focusedDockWidgetChanged, this, &DAAppRibbonArea::onFocusedDockWidgetChanged);
}

/**
 * @brief 通过DACommandInterface构建redo/undo的action
 * @param cmd
 */
void DAAppRibbonArea::buildRedoUndo(DACommandInterface* cmd)
{
    DAAppCommand* cmdapi = dynamic_cast< DAAppCommand* >(cmd);
    Q_ASSERT_X(cmdapi != nullptr, "DAAppRibbonArea::buildRedoUndo", "DACommandInterface* can not cast to DAAppCommand*");
    QUndoGroup& undoGroup = cmdapi->undoGroup();
    //设置redo,undo的action
    m_actionRedo = undoGroup.createRedoAction(this);
    m_actionRedo->setObjectName("actionRedo");
    m_actionRedo->setIcon(QIcon(":/Icon/Icon/redo.svg"));
    m_actionUndo = undoGroup.createUndoAction(this);
    m_actionUndo->setObjectName("actionUndo");
    m_actionUndo->setIcon(QIcon(":/Icon/Icon/undo.svg"));
    retranslateRedoUndo();
    SARibbonQuickAccessBar* bar = ribbonBar()->quickAccessBar();
    if (!bar) {
        return;
    }
    bar->addAction(m_actionUndo);
    bar->addAction(m_actionRedo);
    //注册undoGroup
    cmdapi->setDataManagerStack(&m_dataManagerStack);
}

/**
 * @brief 获取当前dataframeOperateWidget,如果没有返回nullptr
 *
 * 此函数不返回nullptr的前提是:DataOperateWidget处于焦点，且是DataFrameOperateWidget
 * @param checkDataOperateAreaFocused 是否检测DataOperateWidget是否处于焦点，默认为true
 * @return
 */
DADataOperateOfDataFrameWidget* DAAppRibbonArea::getCurrentDataFrameOperateWidget(bool checkDataOperateAreaFocused)
{
    if (nullptr == m_dockArea) {
        return nullptr;
    }
    if (checkDataOperateAreaFocused) {
        if (!(m_dockArea->isDataOperateWidgetFocused())) {
            //窗口未选中就退出
            return nullptr;
        }
    }
    return m_dockArea->getDataOperateWidget()->currentDataFrameWidget();
}

void DAAppRibbonArea::updateActionLockBackgroundPixmapCheckStatue(bool c)
{
}

DAProject* DAAppRibbonArea::getProject() const
{
    // TODO:
    return nullptr;
}

void DAAppRibbonArea::setProject(DAProject* project)
{
    // TODO:
}

/**
 * @brief 设置DataFrame的类型，【Context】 - 【dataframe】 DataFrame -> Type -> Type
 * @param d
 */
void DAAppRibbonArea::setDataframeOperateCurrentDType(const DAPyDType& d)
{
    //先阻塞
    QSignalBlocker blocker(m_comboxColumnTypes);
    Q_UNUSED(blocker);
    m_comboxColumnTypes->setCurrentDType(d);
}

void DAAppRibbonArea::onActionPluginManagerTriggered(bool on)
{
    Q_UNUSED(on);
    DAPluginManagerDialog dlg(ui()->mainWindow());

    dlg.exec();
}

/**
 * @brief DockWidget的焦点变化
 * @param old
 * @param now
 */
void DAAppRibbonArea::onFocusedDockWidgetChanged(ads::CDockWidget* old, ads::CDockWidget* now)
{
    Q_UNUSED(old);
    if (nullptr == now) {
        ribbonBar()->hideContextCategory(m_contextDataFrame);
    }
    //数据操作窗口激活时，检查是否需要显示m_contextDataFrame
    if ((QWidget*)(m_dockArea->getDataOperateWidget()) == now->widget()) {
        //数据窗口激活
        ribbonBar()->showContextCategory(m_contextDataFrame);
    } else if ((QWidget*)(m_dockArea->getDataManageWidget()) == now->widget()) {
        if (!m_dataManagerStack.isActive()) {  // Data 相关的窗口 undostack激活
            m_dataManagerStack.setActive();
        }
        ribbonBar()->hideContextCategory(m_contextDataFrame);
    } else if (now->widget() == (QWidget*)(m_dockArea->getWorkFlowOperateWidget())) {
        m_dockArea->getWorkFlowOperateWidget()->setUndoStackActive();
    }
}

/**
 * @brief 打开文件
 */
void DAAppRibbonArea::onActionOpenTriggered()
{
    QFileDialog dialog(app());
    dialog.setNameFilters(getFileReadFilters());
    if (QDialog::Accepted != dialog.exec()) {
        return;
    }
    QStringList fileNames = dialog.selectedFiles();
    if (fileNames.empty()) {
        return;
    }
    DA_WAIT_CURSOR_SCOPED();
    int importdataCount = 0;
    std::unique_ptr< QUndoCommand > cmdGroup(new QUndoCommand(tr("import files")));
    for (const QString& f : fileNames) {
        DAPyObjectWrapper res = DAPyScripts::getInstance().getIO().read(f);
        if (DAPyDataFrame::isDataFrame(res.object())) {
            QFileInfo fi(f);
            DAPyDataFrame df = res;  //调用的是DAPyDataFrame(const DAPyObjectWrapper& df)
            DAData data      = df;
            data.setName(fi.baseName());
            data.setDescribe(fi.absoluteFilePath());
            new DACommandDataManagerAdd(data, cmdGroup.get());
            ++importdataCount;
        }  // else if() //其他格式
        else if (res.isNone()) {
            continue;
        }
    }
    if (cmdGroup->childCount() > 0) {
        m_dataManagerStack.push(cmdGroup.release());
        m_dockArea->raiseDockByWidget((QWidget*)(m_dockArea->getDataManageWidget()));
    }
}

/**
 * @brief 添加数据
 */
void DAAppRibbonArea::onActionAddDataTriggered()
{
    DAAPPRIBBONAREA_PASS();
}

/**
 * @brief dataframe删除行
 */
void DAAppRibbonArea::onActionRemoveRowTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->removeSelectRow();
    }
}

/**
 * @brief dataframe删除列
 */
void DAAppRibbonArea::onActionRemoveColumnTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->removeSelectColumn();
    }
}

/**
 * @brief 移除单元格
 */
void DAAppRibbonArea::onActionRemoveCellTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->removeSelectCell();
    }
}

/**
 * @brief 插入行
 */
void DAAppRibbonArea::onActionInsertRowTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->insertRowBelowBySelect();
    }
}

void DAAppRibbonArea::onActionInsertRowAboveTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->insertRowAboveBySelect();
    }
}

void DAAppRibbonArea::onActionInsertColumnRightTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->insertColumnRightBySelect();
    }
}

void DAAppRibbonArea::onActionInsertColumnLeftTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->insertColumnLeftBySelect();
    }
}

/**
 * @brief dataframe列重命名
 */
void DAAppRibbonArea::onActionRenameColumnsTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->renameColumns();
    }
}

/**
 * @brief 数据描述
 */
void DAAppRibbonArea::onActionCreateDataDescribeTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        DAPyDataFrame df = dfopt->createDataDescribe();
        if (df.isNone()) {
            return;
        }
        DAData data = df;
        data.setName(tr("%1_Describe").arg(dfopt->data().getName()));
        data.setDescribe(tr("Generate descriptive statistics that summarize the central tendency, dispersion and "
                            "shape of a [%1]’s distribution, excluding NaN values")
                                 .arg(dfopt->data().getName()));
        DACommandDataManagerAdd* cmd = new DACommandDataManagerAdd(data);
        m_dataManagerStack.push(cmd);
        // showDataOperate要在m_dataManagerStack.push之后，因为m_dataManagerStack.push可能会导致data的名字改变
        m_dockArea->showDataOperate(data);
    }
}

/**
 * @brief dataframe的列类型用户手动改变
 * @param index
 */
void DAAppRibbonArea::onComboxColumnTypesCurrentDTypeChanged(const DAPyDType& dt)
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->changeSelectColumnType(dt);
    }
}

/**
 * @brief 选中的列转换为数值
 */
void DAAppRibbonArea::onActionCastToNumTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->castSelectToNum();
    }
}

void DAAppRibbonArea::onActionCastToStringTriggered()
{
}

void DAAppRibbonArea::onActionCastToDatetimeTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->castSelectToDatetime();
    }
}

/**
 * @brief 把某列转换为索引
 */
void DAAppRibbonArea::onActionChangeToIndexTriggered()
{
    if (DADataOperateOfDataFrameWidget* dfopt = getCurrentDataFrameOperateWidget()) {
        dfopt->changeSelectColumnToIndex();
    }
}

void DAAppRibbonArea::onActionShowWorkFlowAreaTriggered()
{
    m_dockArea->raiseDockByWidget((QWidget*)(m_dockArea->getWorkFlowOperateWidget()));
}

void DAAppRibbonArea::onActionShowChartAreaTriggered()
{
    m_dockArea->raiseDockByWidget((QWidget*)(m_dockArea->getChartOperateWidget()));
}

void DAAppRibbonArea::onActionShowDataAreaTriggered()
{
    m_dockArea->raiseDockByWidget((QWidget*)(m_dockArea->getDataOperateWidget()));
}

void DAAppRibbonArea::onActionShowMessageLogViewTriggered()
{
    m_dockArea->raiseDockByWidget((QWidget*)(m_dockArea->getMessageLogViewWidget()));
}

void DAAppRibbonArea::onActionSettingWidgetTriggered()
{
    m_dockArea->raiseDockByWidget((QWidget*)(m_dockArea->getSettingContainerWidget()));
}
